package com.calvin.study.completablefuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import cn.hutool.core.lang.Snowflake;

//任一任务执行完后，执行回调。
public class EitherTaskTest extends BaseThreadPoolExecutor {

	static CompletableFuture<String> future1 = CompletableFuture.supplyAsync(new Supplier<String>() {
		@Override
		public String get() {
			System.out.println("异步任务1，创建订单");
			return "order_id: " + new Snowflake().nextIdStr();
		}
	}, executor);

	static CompletableFuture<String> future2 = CompletableFuture.supplyAsync(new Supplier<String>() {
		@Override
		public String get() {
			try {
				Thread.sleep(3000);
				System.out.println("异步任务2，订单付款");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return "pay_id: " + new Snowflake().nextIdStr();
		}
	}, executor);

	

	public static void applyToEitherTest() throws InterruptedException, ExecutionException {
		//future1、future2两个任务，执行最快的任务再进一步调用该方法
		CompletableFuture<String>  future3 = future1.applyToEitherAsync(future2, new Function<String, String>() {
			@Override
			public String apply(String res) {
				System.out.println("接收任务参数：" + res);
				System.out.println("任务3执行中...");
				return "任务3执行完成";
			}
		}, executor);
		System.out.println(future3.get());
	}
	
	
	public static void acceptEitherTest() {
		//与applyToEitherAsync一样，但调用后没有返回值。
		future1.acceptEitherAsync(future2, new Consumer<String>() {
			@Override
			public void accept(String res) {
				System.out.println("接收任务参数：" + res);
				System.out.println("任务3执行中...");
			}
			
		}, executor);
	}

	public static void runAfterEitherTest() {
		//任何一个完成了都会执行第三步回调操作。 回调函数都是Runnable类型
		future1.runAfterEitherAsync(future2, () -> {
			System.out.println("任务3执行");
		}, executor);
	}
	
	public static void main(String[] args) {
		try {
			//applyToEitherTest();
			//acceptEitherTest();
			//runAfterEitherTest();
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			//System.out.println(executor.isTerminated());
			//executor.shutdown();
		}
	}

}
